package xdu.lz.stage5_jucUtils.chapter5_lock.condition;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Created at 2019/10/19 0019 下午 9:48
 *
 * 三个问题：
 * 1、不使用condition的通知和唤醒机制 ，只是用lock，能也实现生产一个消费一个，那么condition作用？
 *
 * 如果使用的是公平锁，会生产一次，消费一次
 * 但是使用非公平锁，那么会生产多次，消费一次，或者相反。
 */
public class Condition2 {

    private static final ReentrantLock lock = new ReentrantLock(true);

    private static final Condition condition = lock.newCondition();

    private static int data = 0;

    //默认是已经被消费了，也就是要生产
    private static volatile boolean hasConsume = true;

    private static void buildData(){
        try {
            lock.lock();
            //如果没有被消费 ，等待
            /*while (!hasConsume){
                condition.await();
            }*/
            //else : hasConsume = false
            Thread.sleep(10);
            System.out.println("P:"+ ++data);
//            hasConsume = false;
//            //notify
//            condition.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    private static void useData(){
        try {
            lock.lock();
            //如果已经被消费过，则等待
           /* while (hasConsume){
                condition.await();
            }*/
            //indicate: hasConsume false, consume data
            Thread.sleep(10);
            System.out.println(Thread.currentThread().getName()+" consume "+data);
//            hasConsume = true;
//            condition.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        new Thread(()->{
            while (true){
                buildData();
            }
        }).start();
        for (int i = 0; i < 1; i++) {
            new Thread(()->{
                while (true){
                    useData();
                }
            },"consumer "+i).start();
        }
    }
}
